# _new_方法的作用是，创建并返回一个实例对象，如果__new__只调用了一次，就会得到一个对象。
# 继承自object的新式类才有new这一魔法方法。
#
# 注意事项：
# __new__ 是在一个对象实例化的时候所调用的第一个方法
# __new__至少必须要有一个参数cls，代表要实例化的类，此参数在实例化时由Python解释器自动提供 ，
# 其他的参数是用来直接传递给 __init__ 方法
# __new__ 决定是否要使用该 __init__ 方法，
# 因为 __new__ 可以调用其他类的构造方法或者直接返回别的实例对象来作为本类的实例，
# 如果 __new__ 没有返回实例对象，则 __init__ 不会被调用
# 在__new__ 方法中，不能调用自己的__new__ 方法，
# 即：return cls.__new__ (cls)，
# 否则会报错（RecursionError: maximum recursion depth exceeded：超过最大递归深度）


# 单例模式
# 单例模式是常用设计模式的一种，单例就比如我们打开电脑的回收站，
# 在系统中只能打开一个回收站，也就 是说这个整个系统中只有一个实例，重复打开也是使用这个实例。
# 简单的说就是不管创建多少次对象，类返回的对象都是最初创建的，不会再新建其他对象。

class Person:
    __instance=None      #创建了一个变量，用来存储实例对象
    def __init__(self,name,age):
        print("我调用了init方法")
        self.name=name
        self.age=age
        pass
    def __new__(cls, *args, **kwargs):
        print("调用了new方法")
        # 判断实例对象是否存在，若不存在则创建一个新的实例对象并返回
        if not cls.__instance:
            cls.__instance=object.__new__(cls)
            return cls.__instance
        else:#若存在，则直接将已经存在的实例对象返回即可
            return cls.__instance
    pass

xm=Person("小明",22)  #默认情况下，每次创建对象都会返回一个新的对象，单利模式，不管创建不少次，只会返回一个
xh=Person("小红",23)
xz=Person("小朱",24)
print(id(xm))
print(id(xh))
print(id(xz))

